import java.io.*;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: fzykd
 * Date: 2022-04-10
 * Time: 12:37
 */
public class Demo2 { // 读文件

    public static void main4(String[] args) {
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream("d:/test.txt");
                while (true) {
                    int b = inputStream.read();
                    if (b == -1) {
                        break;
                    }
                    System.out.print(b + " ");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) { // 按照字符来读文件
        try(Reader reader = new FileReader("d:/test.txt")){
            // 按照字节来读
            while (true){
                char[] buffer = new char[1024];
                int len = reader.read(buffer);
                if (len == -1){
                    break;
                }
//                for (int i = 0; i < len; i++) {
//                    System.out.println(buffer[i]);
//                }
                //如果这里传入的 数组是byte数组 还可以手动指定一下 utf-8 字符集避免乱码
                String s = new String(buffer,0,len);
                System.out.println(s);
            }
        }catch (IOException e){
            e.printStackTrace();
        }

    }

    public static void main3(String[] args) { //一次读若干个
        try(InputStream inputStream = new FileInputStream("d:/test.txt")){
            //一次读取若干字符
            while (true){
                byte[] buffer = new byte[1024];  // 缓冲区 把文件里读得数据 尽可能往里面填充
                // 这个操作是读出来得结果放到 buffer这个数组中
                // 相当于是使用 参数 来表示方法得返回值
                // 这种做法称为 ”输出型参数“
                int len = inputStream.read(buffer); // 同时返回一个 len
                if (len == -1){
                    // 如果返回-1 说明读取完毕了
                    break;
                }
                for (int i = 0; i < len; i++) {
                    System.out.println(buffer[i]);
                }

            }
        }catch (IOException e){
            e.printStackTrace();
        }


    }


    public static void main2(String[] args) { //这个代码中 没有显示的调用close
        // 但是 try 会帮助我们自动调用
        // try() 括号里得符合一定条件，才能放到try()中 实现Closeable这个interface
        // 恰好所有得流对象 都是实现了Closeable 所有可以直接使用
        try (InputStream inputStream = new FileInputStream("d:/test.txt")){
            while (true){
                int b =inputStream.read();
                if (b == -1){
                    break;
                }
                System.out.println(b);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }


    //main1代码过于 啰嗦 main2 改进 用到了try with resources 改进
    public static void main1(String[] args) {
        //方法中需要指定打开文件的路径
        //此路径可以是相对路径 也可以是 绝对路径  还可以是File 对象
        InputStream inputStream = null;
        try { //此时会抛出一个异常 文件没找到异常
            //1.创建对象 也是在打开文件
            inputStream = new FileInputStream("d:/test.txt"); // InputStream是一个抽象类
            //2.尝试一个字节一个字节的读，把整个文件都读完
            while (true){
                int b = inputStream.read();
                if (b == -1){
                    // 读到了文件末尾
                    break;
                }
                System.out.println(b);
            }
        } catch (IOException e) {  // 文件未找到异常
            e.printStackTrace();

        }finally {
            //3. 读完之后接的关闭文件 释放资源
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // IO 读操作的时候的异常  IO操作失败的肯能性是非常大的
        // 这个异常也是 IOException的子类 catch合并起来

        //不能直接new 一个抽象类 而是new 一个具体的能实现的类
    }
}
